﻿using System;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Expressions;
using System.Activities.Presentation.PropertyEditing;
using System.Activities.Statements;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Markup;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace Vision.Core.ActivityComponents.Sql
{
    /// <summary>
    /// 
    /// </summary>
    [ContentProperty("Body")]
    [System.ComponentModel.Designer(typeof(SqlConnectionDesigner))]
    public class SqlConnection : NativeActivity
    {
        private System.Data.SqlClient.SqlConnection SqlConn { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        public ActivityAction<System.Data.SqlClient.SqlConnection> Body { get; set; }
        
        [Category("Input")]
        [RequiredArgument]        
        [DefaultValue(null)]
        public InArgument<string> ConnectionString { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public SqlConnection() : base()
        {
            this.Body = new ActivityAction<System.Data.SqlClient.SqlConnection>(){
                Argument = new DelegateInArgument<System.Data.SqlClient.SqlConnection>() { Name = "sqlConn" }
            };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="metadata"></param>
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            RuntimeArgument connectionStringArgument = new RuntimeArgument("ConnectionString", typeof(string), ArgumentDirection.In, true);
            metadata.Bind(this.ConnectionString, connectionStringArgument);
            metadata.AddArgument(connectionStringArgument);

            metadata.AddDelegate(this.Body);   
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void Execute(NativeActivityContext context)
        {
            if (this.Body != null && this.Body.Handler != null){
                this.SqlConn = new System.Data.SqlClient.SqlConnection();
                this.SqlConn.ConnectionString = this.ConnectionString.Get(context);                
                this.SqlConn.Open();                                
                
                context.ScheduleAction(this.Body, this.SqlConn, this.OnBodyCompleted, this.OnBodyFaulted);
            }                
        }
                
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instance"></param>
        private void OnBodyCompleted(NativeActivityContext context, ActivityInstance instance)
        {
            if (this.SqlConn != null){
                if (this.SqlConn.State == System.Data.ConnectionState.Open){
                    this.SqlConn.Close();
                }
                this.SqlConn.Dispose();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="faultContext"></param>
        /// <param name="propagatedException"></param>
        /// <param name="propagatedFrom"></param>
        private void OnBodyFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
        {
            if (this.SqlConn != null){
                if (this.SqlConn.State == System.Data.ConnectionState.Open){
                    this.SqlConn.Close();
                }
                this.SqlConn.Dispose();
            }
        }
    }
}
